package com.promise.jokerdream.ui.webview

import android.annotation.SuppressLint
import android.content.Context
import android.content.Intent
import android.net.Uri
import android.os.Handler
import android.os.Looper
import android.util.Log
import android.webkit.CookieManager
import android.webkit.WebResourceError
import android.webkit.WebResourceRequest
import android.webkit.WebView
import android.webkit.WebViewClient
import com.promise.jokerdream.manager.FightProcessManager
import com.promise.jokerdream.network.HttpApiConstants
import kotlinx.coroutines.CoroutineScope
import kotlinx.coroutines.Dispatchers
import kotlinx.coroutines.SupervisorJob
import kotlinx.coroutines.launch

/**
 * 自定义WebViewClient
 * 处理页面加载、错误处理、URL拦截等功能
 */
class CustomWebViewClient(
    private val context: Context,
    private val callback: IWebViewCallback
) : WebViewClient() {

    private val TAG = "CustomWebViewClient"
    private val mainHandler = Handler(Looper.getMainLooper())
    private val coroutineScope = CoroutineScope(SupervisorJob() + Dispatchers.Main)
    private val fightProcessManager = FightProcessManager.getInstance()

    /**
     * 移除URI中指定的查询参数
     */
    private fun removeQueryParameter(uri: Uri, parameterName: String): Uri {
        val uriBuilder = uri.buildUpon().clearQuery()

        // 重新添加除了指定参数之外的所有查询参数
        uri.queryParameterNames?.forEach { paramName ->
            if (paramName != parameterName) {
                uri.getQueryParameters(paramName)?.forEach { paramValue ->
                    uriBuilder.appendQueryParameter(paramName, paramValue)
                }
            }
        }

        return uriBuilder.build()
    }

    /**
     * 确保在主线程中执行操作
     */
    private fun runOnMainThread(action: () -> Unit) {
        if (Looper.myLooper() == Looper.getMainLooper()) {
            action()
        } else {
            mainHandler.post(action)
        }
    }

    override fun onPageFinished(view: WebView?, url: String?) {
        super.onPageFinished(view, url)
        url?.let { callback.onPageFinished(it) }
        
        // 注入无痕模式JS修正
        if (com.promise.jokerdream.utils.IncognitoPreferenceManager.isIncognitoEnabled(context)) {
            injectIncognitoFix(view)
        }

        url?.let { currentUrl ->
            // 检测是否离开了viewfight页面，如果是则取消战斗过程解析
            try {
                val uri = Uri.parse(currentUrl)
                val cmdParam = uri.getQueryParameter("cmd")
                val hasViewFight = cmdParam == "viewfight"
                
                // 如果当前页面不是viewfight页面，且正在解析战斗过程，则取消
                if (!hasViewFight) {
                    val currentId = fightProcessManager.getCurrentId()
                    if (currentId != null) {
                        Log.d(TAG, "检测到离开viewfight页面，取消战斗过程解析")
                        fightProcessManager.cancel()
                        callback.onFightProcessCancelled()
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "检测viewfight页面状态失败: ${e.message}")
            }
            
            // 只有在特定路径下才解析cookie
            if (currentUrl == HttpApiConstants.PhoneUrls.home) {
                try {
                    val cookieManager = CookieManager.getInstance()
                    // 只有登录的时候才能从https://dld.qzapp.z.qq.com获取cookie
                    val cookies = cookieManager.getCookie(HttpApiConstants.PhoneUrls.base)
                    if (!cookies.isNullOrEmpty() && cookies.contains("accessToken")) {
                        // 检测到登录Cookie，提取用户信息
                        val usernameMatch = Regex("newuin=([^;]+)").find(cookies)
                        val userId = if (usernameMatch != null) {
                            "${usernameMatch.groupValues[1]}"
                        } else {
                            "123456789"
                        }
                        val username = userId // 先这样
                        callback.onLoginDetected(userId, username, cookies)
                        Log.d(TAG, "检测到登录状态: $username")
                    }
                } catch (e: Exception) {
                    Log.e(TAG, "检测登录状态失败: ${e.message}")
                }
            }
        }
    }
    
    override fun onReceivedError(view: WebView?, request: WebResourceRequest?, error: WebResourceError?) {
        super.onReceivedError(view, request, error)
        Log.e(TAG, "加载错误: ${error?.description}，URL: ${request?.url}")
    }

    override fun shouldOverrideUrlLoading(view: WebView?, request: WebResourceRequest?): Boolean {
        request?.url?.let { uri ->
            Log.i(TAG, "即将加载url: ${uri}")
            try {
                when (uri.scheme?.lowercase()) {
                    "http", "https" -> {
                        val urlString = uri.toString()
                        val cmdParam = uri.getQueryParameter("cmd")
                        val pageParam = uri.getQueryParameter("page")
                        val hasViewFight = cmdParam == "viewfight"
                        val isFirstPage = pageParam == "1" || pageParam == null
                        
                        if (hasViewFight) {
                            if (isFirstPage) {
                                handleViewFightUrl(view, urlString)
                            }
                        } else {
                            fightProcessManager.cancel()
                            callback.onFightProcessCancelled()
                        }
                        return false
                    }
                    null -> return false

                    else -> {
                        Log.d(TAG, "尝试打开三方应用，scheme: ${uri.scheme}")
                        try {
                            // 使用通用方法移除schemacallback参数
                            val cleanedUri = removeQueryParameter(uri, "schemacallback")

                            // 检查是否有应用可以处理这个Intent
                            val intent = Intent(Intent.ACTION_VIEW, cleanedUri)
                            intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK)
                            // 确保在主线程中启动Activity
                            runOnMainThread {
                                context.startActivity(intent)
                            }
                            return true
                        } catch (e: Exception) {
                            Log.e(TAG, "打开三方应用失败: ${e.message}")
                            return true
                        }
                    }
                }
            } catch (e: Exception) {
                Log.e(TAG, "处理URL scheme失败", e)
            }
        }
        return super.shouldOverrideUrlLoading(view, request)
    }
    
    private fun handleViewFightUrl(view: WebView?, url: String) {
        view ?: return
        
        coroutineScope.launch {
            try {
                Log.d(TAG, "开始解析战斗过程: $url")
                val result = fightProcessManager.getCompleteFightProcess(url) { currentPage, totalPages, content ->
                    Log.d(TAG, "解析进度: $currentPage/$totalPages")
                    callback.onFightProcessProgress(currentPage, totalPages)
                }
                
                result.fold(
                    onSuccess = { xmlContent ->
                        Log.d(TAG, "解析完成，替换WebView内容")
                        callback.onFightProcessCompleted()
                        runOnMainThread {
                            view.loadDataWithBaseURL(
                                url,
                                xmlContent,
                                "text/html",
                                "UTF-8",
                                null
                            )
                        }
                    },
                    onFailure = { error ->
                        Log.e(TAG, "解析失败: ${error.message}")
                        if (error.message?.contains("相同ID") == true) {
                            callback.onFightProcessCancelled()
                        } else {
                            callback.onFightProcessCompleted()
                        }
                    }
                )
            } catch (e: Exception) {
                Log.e(TAG, "处理viewfight URL异常: ${e.message}", e)
                callback.onFightProcessCompleted()
            }
        }
    }

    /**
     * 注入JS以解决无痕模式下访问过的链接变色问题，同时保留点击/悬停效果
     */
    private fun injectIncognitoFix(view: WebView?) {
        val js = """
            (function() {
                var styleId = 'incognito-mode-style-override';
                if (document.getElementById(styleId)) return; // 避免重复注入核心逻辑
                
                var styleEl = document.createElement('style');
                styleEl.id = styleId;
                document.head.appendChild(styleEl);
                
                var colorMap = {};
                var classCounter = 0;
                
                function fixLinkColors() {
                    var links = document.getElementsByTagName('a');
                    var newRules = [];
                    
                    for (var i = 0; i < links.length; i++) {
                        var link = links[i];
                        // 忽略已有标记
                        if (link.getAttribute('data-incognito-fixed')) continue;

                        // 清理旧的内联样式
                        if (link.style.color && link.getAttribute('data-old-fix')) { link.style.color = ''; }

                        var color = window.getComputedStyle(link).color;
                        if (!color) continue;
                        
                        var className = colorMap[color];
                        if (!className) {
                            className = 'incog_' + classCounter++;
                            colorMap[color] = className;
                            // 核心：只覆盖 visited 且非 active/hover 状态
                            newRules.push('.' + className + ':visited:not(:active):not(:hover) { color: ' + color + ' !important; }');
                        }
                        
                        link.classList.add(className);
                        link.setAttribute('data-incognito-fixed', 'true');
                    }
                    
                    if (newRules.length > 0) styleEl.textContent += newRules.join('\n');
                }
                
                fixLinkColors();
                new MutationObserver(fixLinkColors).observe(document.body, { childList: true, subtree: true });
            })();
        """.trimIndent()
        view?.evaluateJavascript(js, null)
    }
}

